package com.wanxing.sellerapp.upload

import android.content.Context
import com.wanxing.sellerapp.AppExecutors
import com.wanxing.sellerapp.config.AppConfig
import com.wanxing.sellerapp.data.bean.SyncOrder
import com.wanxing.sellerapp.data.bean.SyncVideo
import com.wanxing.sellerapp.data.db.LocalDB
import com.wanxing.sellerapp.platform.Api
import com.wanxing.sellerapp.seller.events.ShowLogEvent
import org.greenrobot.eventbus.EventBus
import java.io.File
import java.util.UUID
import java.util.concurrent.DelayQueue

class Uploader(context:Context) {

    private val db = LocalDB.get(context)
    private val oss = AliyunOSS(context)
    private val syncOrderDao = db.syncOrderDao()
    private val syncVideoDao = db.syncVideoDao()
    private val uploadQueue = DelayQueue<ReUploadToOssDelay>()
    private val syncQueue = DelayQueue<ReSyncToServiceDelay>()
    private val syncVideoQueue = DelayQueue<ReSyncVideoDelay>()

    private var active = false

    private val uploaderTaskHandler = Thread({
        while (active) {
            val delay = uploadQueue.take()
            val filepath = delay.filePath
            val file = File(filepath)
            if (file.exists()) {
                if (file.length() < 1) {
                    file.delete()
                }else {
                    val filename = file.name
                    if (filename.contains("_")) {
                        val names = filename.split("_")
                        val date = names[0]
                        val name = names[1] + "_" + names[2]
                        val success = oss.upload("videos/$date/$name", filepath)
                        // 若上传成功，就删除文件
                        if (success) {
                            val oid = name.split(".")[0];
                            val old = syncVideoDao.getByOrderId(oid)
                            if (old == null) {
                                syncVideoDao.insertAll(SyncVideo(oid))
                                syncVideoQueue.offer(ReSyncVideoDelay(oid))
                            }
                            EventBus.getDefault()
                                .post(ShowLogEvent("oss上传成功：$filename", filename))
                            file.delete()
                        }  // 若上传失败则重新上传
                        else {
                            EventBus.getDefault()
                                .post(ShowLogEvent("oss上传失败：$filename", filename))
                            uploadQueue.offer(ReUploadToOssDelay(filepath))
                        }
                    } else {
                        file.delete()
                    }
                }
            }

        }
    },"uploaderTaskHandler")

    private val syncTaskHandler = Thread({
        while (active) {
            val delay = syncQueue.take()
            val orderId = delay.orderId
            val status = delay.status
            val id = delay.id
            // 同步成功后删除记录
            if (Api.updateOrder(orderId, status)) {
                EventBus.getDefault().post(ShowLogEvent("同步订单状态成功：$status", orderId))
                syncOrderDao.deleteRecord(SyncOrder(id, orderId, status))
            }
            // 同步不成功继续同步
            else{
                EventBus.getDefault().post(ShowLogEvent("同步订单状态失败：$status", orderId))
                syncQueue.offer(ReSyncToServiceDelay(orderId, status, id))
            }

        }
    },"syncTaskHandler")
    private val syncVideoHandler = Thread({
        while (active) {
            val delay = syncVideoQueue.take()
            val order = delay.orderId.split("_")
            val orderId = order[0]
            val type = order[1]
            // 同步成功后删除记录
            if (Api.updateVideo(orderId, type)) {
                EventBus.getDefault().post(ShowLogEvent("同步视频状态成功", delay.orderId))
                syncVideoDao.deleteRecord(SyncVideo(delay.orderId))
            }
            // 同步不成功继续同步
            else{
                EventBus.getDefault().post(ShowLogEvent("同步视频状态失败", delay.orderId))
                syncVideoQueue.offer(ReSyncVideoDelay(delay.orderId))
            }
        }
    },"syncVideoHandler")

    fun uploadVideo(filename: String) {
        uploadQueue.offer(ReUploadToOssDelay(100, filename.replace("""${'$'}error"""  , "")))
    }

    fun syncOrder(orderId: String, state: String) {
        val uuid = UUID.randomUUID().toString().replace("-", "")
        val syncOrder = SyncOrder(uuid, orderId, state)
        syncOrderDao.insertAll(syncOrder)
        syncQueue.offer(ReSyncToServiceDelay(50, syncOrder.orderId, syncOrder.state, syncOrder.id))
    }

    fun deleteVideo(filename: String){
        val file = File(filename)
        if (file.exists()) file.delete()
    }

    fun run() {
        val dir = File(AppConfig.VIDEO_SAVE_PATH)
        if (!dir.exists()){
            dir.mkdirs()
        }
        dir.listFiles().forEach {
            // 重启后重新上传视频
            uploadQueue.offer(ReUploadToOssDelay(1500, it.absolutePath))
        }
        AppExecutors.diskIO.execute {
            // 重启后同步没有同步的订单状态
            syncOrderDao.getAll().forEach {
                syncQueue.offer(ReSyncToServiceDelay(1000, it.orderId, it.state, it.id))
            }
            // 重启后同步没有同步的视频上传状态
            syncVideoDao.getAll().forEach {
                syncVideoQueue.offer(ReSyncVideoDelay(1000, it.id))
            }
        }
        active = true
        uploaderTaskHandler.start()
        syncTaskHandler.start()
        syncVideoHandler.start()
    }

    fun release(){
        active = false
        uploaderTaskHandler.interrupt()
        syncTaskHandler.interrupt()
        syncVideoHandler.interrupt()
    }
}